package com.my.stock.core;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import org.zeromq.ZMQ;

import com.my.myTradeData.JavaFile;
import com.my.myTradeData.MathUtil;
import com.my.myTradeData.TechnicalAnalysisIndicators;
import com.my.myTradeData.TickData;
import com.my.myTradeData.DataSource.Dictionary;
import com.my.myTradeData.DataSource.Sina;

import net.sf.json.JSONObject;

public class KLineServer {

	public static BlockingQueue<String> signalQueue = new ArrayBlockingQueue<String>(1024);

	public String code = "";

	public List<KLine> kline15mins = new ArrayList<KLine>();
	public KLine klineTickBuffer = null;
//	public double codeSTD = 0;
	public double ATR = 0;

	private static List<Double> KLinePriod = new ArrayList<Double>();

	static {
		initDayDate();
		initNightDate();
	}

	public static void initDayDate() {
		double d = 0.091450;
		KLinePriod.add(d);
		d = 0.092950;
		KLinePriod.add(d);
		d = 0.094450;
		KLinePriod.add(d);
		d = 0.095950;
		KLinePriod.add(d);
		d = 0.101450;
		KLinePriod.add(d);
		d = 0.104450;
		KLinePriod.add(d);
		d = 0.105950;
		KLinePriod.add(d);
		d = 0.111450;
		KLinePriod.add(d);
		d = 0.112950;
		KLinePriod.add(d);
		d = 0.134450;
		KLinePriod.add(d);
		d = 0.135950;
		KLinePriod.add(d);
		d = 0.141450;
		KLinePriod.add(d);
		d = 0.142950;
		KLinePriod.add(d);
		d = 0.144450;
		KLinePriod.add(d);
		d = 0.145950;
		KLinePriod.add(d);

	}

	public static void initNightDate() {
		double d = 0.211455;
		KLinePriod.add(d);
		d = 0.212955;
		KLinePriod.add(d);
		d = 0.214455;
		KLinePriod.add(d);
		d = 0.215955;
		KLinePriod.add(d);
		d = 0.221455;
		KLinePriod.add(d);
		d = 0.222955;
		KLinePriod.add(d);
		d = 0.224455;
		KLinePriod.add(d);
		d = 0.225955;
		KLinePriod.add(d);
		d = 0.231455;
		KLinePriod.add(d);
		d = 0.232955;
		KLinePriod.add(d);
		d = 0.234455;
		KLinePriod.add(d);
		d = 0.235955;
		KLinePriod.add(d);
		d = 0.001455;
		KLinePriod.add(d);
		d = 0.002955;
		KLinePriod.add(d);
		d = 0.004455;
		KLinePriod.add(d);
		d = 0.005955;
		KLinePriod.add(d);
		d = 0.011455;
		KLinePriod.add(d);
		d = 0.012955;
		KLinePriod.add(d);
		d = 0.014455;
		KLinePriod.add(d);
		d = 0.015955;
		KLinePriod.add(d);
		d = 0.021455;
		KLinePriod.add(d);
		d = 0.022955;
	}

	public static void start() throws IOException {

		List<String> codeList = Sina.getMainCode();

		for (String code : codeList) {
			System.out.println("\"" + code + "\",");
		}

//		codeList.add("SF005");
//		codeList.add("SM005");
//		codeList.add("bu2005");
//		codeList.add("l2005");
//		codeList.add("TA005");
//		codeList.add("J005");
//		codeList.add("a2005");
//		codeList.add("p2005");
//		codeList.add("c2005");
//		codeList.add("rb2005");
//		codeList.add("OI005");
////		codeList.add("pb2005");
//		codeList.add("b2005");
////		codeList.add("RM005");
//		codeList.add("ru2005");
//		codeList.add("m2005");
//		codeList.add("v2005");
//		codeList.add("pp2005");
//		codeList.add("SR005");
//		codeList.add("CF005");
//		codeList.add("cs2005");
//		codeList.add("i2005");
//		codeList.add("sn2005");
		for (String code : codeList) {
			KLineServer k = new KLineServer();
			List<KLine> klist = new ArrayList<KLine>();
			File file = new File(BASE_PATH + code + ".txt");
			if (file.exists()) {
				List<String> ks = JavaFile.readfile(BASE_PATH + code + ".txt");
				for (String kline : ks) {
					JSONObject json = JSONObject.fromObject(kline);
					KLine kl = (KLine) JSONObject.toBean(json, KLine.class);
					klist.add(kl);
				}
			} else {
				klist = Sina.get15mData(code);
				String writeStr = "";
				double[] d = new double[klist.size()];
				for (int i = klist.size() - 1; i > 1; i--) {
					klist.get(i).setTr(TechnicalAnalysisIndicators.getTr(klist.get(i), klist.get(i - 1)));
					d[i] = klist.get(i).getTr();
					JSONObject json = JSONObject.fromObject(klist.get(i));// 将java对象转换为json对象
					String str = json.toString();
					writeStr = writeStr + str + "\r\n";
				}
				k.ATR = MathUtil.getAverage(d);
				JavaFile.writefile(BASE_PATH + code + ".txt", writeStr);
			}

			k.kline15mins = klist;
			k.code = code;
//			k.codeSTD = MathUtil.getStandardDiviation(d);
			k.tickThread.start();

		}
		
		KLineServer k = new KLineServer();
		k.tickThread.start();
		
//		workingtickThread.start();
	}

	public Thread tickThread = new Thread(new Runnable() {

		public void run() {

			ZMQ.Context context = ZMQ.context(1);
			ZMQ.Socket s = context.socket(ZMQ.SUB);
			s.connect("tcp://127.0.0.1:5556");
			s.subscribe(code.getBytes());

			String subCode = code;
			while (true) {

				try {
					byte recStr[] = s.recv();
					String sg = new String(recStr, "utf-8");

					String code = sg.split(",")[0];

					if (!code.equals(subCode)) {
						continue;
					}

					System.out.println(sg);

//					sg = sg.replaceAll(code + ",", "");
//
//					String data[] = sg.split(",");
//					TickData t = new TickData();
//					t.setAveragePrice(Double.parseDouble(data[0]));
//					t.setBuyPrice(Double.parseDouble(data[2]));
//					t.setSellPrice(Double.parseDouble(data[1]));
//					SimpleDateFormat myFmt1 = new SimpleDateFormat("yyyyMMdd hh:mm:ss SSS");
//					t.setTickDate(myFmt1.parse(data[5].replaceAll("#", " ")));
////					t.setT(Double.parseDouble(data[6]));
//
//					if (klineTickBuffer == null) {
//						klineTickBuffer = new KLine();
//						klineTickBuffer.setClose(t.getAveragePrice());
//						klineTickBuffer.setOpen(t.getAveragePrice());
//						klineTickBuffer.setHigh(t.getAveragePrice());
//						klineTickBuffer.setLow(t.getAveragePrice());
//						klineTickBuffer.setDate(t.getTickDate());
//						klineTickBuffer.setTr(TechnicalAnalysisIndicators.getTr(klineTickBuffer,
//								kline15mins.get(kline15mins.size() - 1)));
//
//					} else {
//
//						if (isLast(klineTickBuffer, t)) {
//							drawKLine(klineTickBuffer, code);
//						} else {
//							klineTickBuffer.setClose(t.getAveragePrice());
//							if (t.getAveragePrice() > klineTickBuffer.getHigh()) {
//								klineTickBuffer.setHigh(t.getAveragePrice());
//							}
//							if (t.getAveragePrice() < klineTickBuffer.getLow()) {
//								klineTickBuffer.setLow(t.getAveragePrice());
//							}
//							klineTickBuffer.setDate(t.getTickDate());
//
//							klineTickBuffer.setTr(TechnicalAnalysisIndicators.getTr(klineTickBuffer,
//									kline15mins.get(kline15mins.size() - 1)));
//
//						}
//					}
//
//
//					if (klineTickBuffer != null && klineTickBuffer.getTr() > ATR * 3 && kline15mins.size() > 80) {
//
//						double pri = klineTickBuffer.getClose();
//
//						if (klineTickBuffer.getClose() > kline15mins.get(kline15mins.size() - 1).getClose()) {
//							if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 1) {
//								pri = Math.floor(pri) - 1;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 2) {
//								pri = Math.floor(pri * 0.5) * 2 - 2;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 5) {
//								pri = Math.floor(pri * 0.2) * 5 - 5;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 10) {
//								pri = Math.floor(pri * 0.1) * 10 - 10;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.2) {
//								pri = Math.floor(pri * 5) * 0.2 - 0.2;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.5) {
//								pri = Math.floor(pri * 2) * 0.5 - 0.5;
//							}
//							signalQueue.offer("buy," + code + ",1," + pri + "," + pri + "\0");
//						} else {
//
//							if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 1) {
//								pri = Math.floor(pri) + 1;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 2) {
//								pri = Math.floor(pri * 0.5) * 2 + 2;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 5) {
//								pri = Math.floor(pri * 0.2) * 5 + 5;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 10) {
//								pri = Math.floor(pri * 0.1) * 10 + 10;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.2) {
//								pri = Math.floor(pri * 5) * 0.2 + 0.2;
//							} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.5) {
//								pri = Math.floor(pri * 2) * 0.5 + 0.5;
//							}
//
//							signalQueue.offer("sell," + code + ",1," + pri + "," + pri + "\0");
//						}
//
//					}
//
//				} catch (Throwable e) {
//					e.printStackTrace();
//				}
//
			}

		}
	});

	private static Thread workingtickThread = new Thread(new Runnable() {

		public void run() {

			ZMQ.Context context = ZMQ.context(1);
			ZMQ.Socket s = context.socket(ZMQ.REQ);
			s.connect("tcp://127.0.0.1:5557");

			while (true) {
				try {
					String sigal = signalQueue.take();
					System.out.println(sigal);
					s.send(sigal);
					String r=s.recvStr();
					System.out.print(r);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}

		}
	});

	private boolean isLast(KLine buffer, TickData da) {
		int i = getPeriod(buffer.getDate());
		int i1 = getPeriod(da.getTickDate());

		System.out.println("i---------" + i);
		System.out.println("i---------" + i1);

		if (i1 - i == 1) {
			return true;
		} else {
			return false;
		}
	}

	private static int getPeriod(Date d) {

		int j = 0;

		if (DateUtil.getETime(d) < 0.0845) {
			j = 27;
		}

		for (int i = j; i < KLinePriod.size(); i++) {

			if (DateUtil.getETime(d) > KLinePriod.get(i)) {

			} else {
				return i;
			}

		}

		return -1;

	}

	private static String BASE_PATH = "e:\\codeKline\\";

	private void drawKLine(KLine buffer, String code) {

		kline15mins.add(buffer);

		double[] d = new double[kline15mins.size()];
		for (int i = 0; i < kline15mins.size(); i++) {
			kline15mins.get(i)
					.setTr(TechnicalAnalysisIndicators.getTr(buffer, kline15mins.get(kline15mins.size() - 1)));
			d[i] = kline15mins.get(i).getTr();
		}
		
		JSONObject json = JSONObject.fromObject(buffer);// 将java对象转换为json对象
		String str = json.toString();
		try {
			JavaFile.writefile(BASE_PATH + code + ".txt", str + "\r\n", true);
		} catch (IOException e) {
			e.printStackTrace();
		}

//		codeSTD = MathUtil.getStandardDiviation(d);

		klineTickBuffer = null;

	}

	public static void main(String args[]) throws ParseException, IOException {

//		SimpleDateFormat myFmt1 = new SimpleDateFormat("yyyyMMdd hh:mm:ss SSS");
//
//		Date d = myFmt1.parse("20001111 08:45:00 000");
//
//		for (int i = 0; i < 111; i++) {
//			d = new Date(d.getTime() + 15 * 60000);
////			System.out.println(d);
////			System.out.println(DateUtil.getETime(d));
//
//			System.out.println(getPeriod(d));
//		}

		KLineServer.start();

	}
}
